package fifis.game.common;

import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AppStateManager;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.material.Material;
import com.jme3.material.MaterialDef;
import com.jme3.renderer.Camera;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import java.util.HashMap;
import org.apache.log4j.Logger;

/**
 *
 * @author porfiriopartida
 */
public class Common {
    public final static Logger LOG = Logger.getLogger("GLOBAL"); // should not being used
    
    protected final static Logger log4j = Logger.getLogger(Common.class);

    public final static String SEPz = System.getProperty("file.separator");
//    public final static String MODELS = "Models" + SEP;
    static Material unshaded;
    AssetManager assetManager;
    AppStateManager stateManager;
    BulletAppState bulletAppState;
    Node rootNode;
    SimpleApplication currentApplication;
    Camera camera;
    Node guiNode;
    static HashMap<String, Material> materials = new HashMap<String, Material>();
    static HashMap<String, Node> nodes = new HashMap<String, Node>();

    private Common() {
    }
    private static Common self;

    public static Common getInstance() {
        if (self == null) {
            self = new Common();
        }
        return self;
    }

    public AssetManager getAssetManager() {
        return assetManager;
    }

    /**
     * Gets the saved common rootNode, this must be the SimpleApplication rootNode 
     * 
     * @return The rootNode object (null if never being set)
     */
    public Node getRootNode() {
        return rootNode;
    }

    public void setRootNode(Node rootNode) {
        this.rootNode = rootNode;
        log4j.debug("rootNode loaded " + rootNode);
    }

    public BulletAppState getBulletAppState() {
        return bulletAppState;
    }

    public void setBulletAppState(BulletAppState bulletAppState) {
        this.bulletAppState = bulletAppState;
        stateManager.attach(bulletAppState);

//        bulletAppState.getPhysicsSpace().enableDebug(assetManager);
    }

    public SimpleApplication getCurrentApplication() {
        return currentApplication;
    }

    public void setCurrentApplication(SimpleApplication currentApplication) {
        this.currentApplication = currentApplication;
    }

    public AppStateManager getStateManager() {
        return stateManager;
    }

    public void setStateManager(AppStateManager stateManager) {
        this.stateManager = stateManager;
    }

    public Node getGuiNode() {
        return guiNode;
    }

    public void setGuiNode(Node guiNode) {
        this.guiNode = guiNode;
    }

    public void setAssetManager(AssetManager assetManager) {
        Common.getInstance().assetManager = assetManager;
        log4j.debug("AssetManager loaded " + assetManager);
    }

//    public void setAssetManager(Node rootNode) {
//        Common.getInstance().rootNode = rootNode;
//        log4j.debug("rootNode loaded");
//    }

    public Node getBox(String nodeName) {
        Node boxNode = new Node();
        Box box = new Box();
        Geometry geom = new Geometry(nodeName, box);
        geom.setMaterial(getUnshaded());
        boxNode.attachChild(geom);
        return boxNode;
    }

    public Material getUnshaded() {
        if (unshaded != null) {
            return unshaded;
        } else {
            MaterialDef md = (MaterialDef) assetManager.loadAsset("Common/MatDefs/Misc/Unshaded.j3md");
            unshaded = new Material(md);
        }

        return unshaded;
    }

    public Material getMaterial(String material) {
        Material mat = materials.get(material);
        if (mat == null) {
            mat = assetManager.loadMaterial(material);
            materials.put(material, mat);
        }
        return mat;
    }

    public Material getMaterial(String material, boolean safe) {
        Material mat = getMaterial(material);
        if (safe) {
            if (mat == null) {
                mat = getUnshaded();
            }
        }
        return mat;
    }

    public Node getNode(String nodePath) {
        return getNode(nodePath, nodePath);
    }

    public Node getNode(String nodePath, String nodeName) {
        Node node = nodes.get(nodePath);
        if (node == null) {
            node = (Node) assetManager.loadModel(nodePath);
            nodes.put(nodePath, node);
        }
        node.setName(nodeName);
        return node.clone(true);
    }

    public Node getNode(String nodePath, String nodeName, boolean safe) {
        Node node = getNode(nodePath);
        if (safe) {
            if (node == null) {
                log4j.warn("Safe node used.");
                node = getBox(nodeName);
            }
        }
        node.setName(nodeName);
        return node;
    }

    public Node getNode(String nodePath, String nodeName, Node safe) {
        Node node = getNode(nodePath);

        if (node == null) {
            log4j.warn("Safe node used.");
            return safe;
        }

        return node;
    }

    public Camera getCamera() {
        return camera;
    }

    public void setCamera(Camera camera) {
        this.camera = camera;
    }
}
